#pragma once

#ifndef Parent_h
#define Parent_h

#include "Standards.h"
#include "StmtTable.h"
#include "VarTable.h"
#include "Schema.h"

using namespace std;

class Parent
{
	public:
		unordered_multimap<INDEX, INDEX> parentTableStmt;
		unordered_multimap<INDEX, INDEX> parentTableStmtClosure;
		StmtTable* myST;
		VarTable* myVT;
		
		//! Constructor (takes in the VarTable and stmtTable)
		Parent(VarTable*, StmtTable*);

		/*! 
		  A method that computes and stores the transitive closures
		*/
		void computeClosure();

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,s2)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getSynSyn(DESIGN_ENTITY,NAME,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,3)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param INDEX 3
		*/
		Schema getSynInt(DESIGN_ENTITY,NAME,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,_)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		*/
		Schema getSynUnd(DESIGN_ENTITY,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,s2)
		  \param INDEX 3
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getIntSyn(INDEX,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,4)
		  \param INDEX 3
		  \param INDEX 4
		*/
		Schema getIntInt(INDEX,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,_)
		  \param INDEX 3
		*/
		Schema getIntUnd(INDEX);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,3)
		  \param INDEX 3
		*/
		Schema getUndInt(INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,s2)
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getUndSyn(DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,_)
		*/
		Schema getUndUnd();
		
	

		//.................................................


				//...Closure...

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,s2)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getSynSynClosure(DESIGN_ENTITY,NAME,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,3)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		  \param INDEX 3
		*/
		Schema getSynIntClosure(DESIGN_ENTITY,NAME,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(s1,_)
		  \param DESIGN_ENTITY design-entity of s1
		  \param NAME s1
		*/
		Schema getSynUndClosure(DESIGN_ENTITY,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,s2)
		  \param INDEX 3
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getIntSynClosure(INDEX,DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,4)
		  \param INDEX 3
		  \param INDEX 4
		*/
		Schema getIntIntClosure(INDEX,INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(3,_)
		  \param INDEX 3
		*/
		Schema getIntUndClosure(INDEX);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,3)
		  \param INDEX 3
		*/
		Schema getUndIntClosure(INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,s2)
		  \param DESIGN_ENTITY design-entity of s2
		  \param NAME s2
		*/
		Schema getUndSynClosure(DESIGN_ENTITY,NAME);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Parent(_,_)
		*/
		Schema getUndUndClosure();

		//................................................
		/*! 
		  A method that prints the contents of the Parent table
		*/
		void printAll();
		
		/*! 
		  A method that inserts tuple <x,y> into Parent table signifying x is a parent of y
		  \param INDEX parent
		  \param INDEX child
		*/
		void set(INDEX, INDEX);

	private:
		int count;
};

#endif